package com.ffggffgfv.backend.service.impl;

import com.alibaba.fastjson.JSON;
import com.ffggffgfv.backend.dto.BatchRestockDTO;
import com.ffggffgfv.backend.dto.PageResult;
import com.ffggffgfv.backend.dto.RestockDTO;
import com.ffggffgfv.backend.dto.ShelfProductDetailDTO;
import com.ffggffgfv.backend.entity.Product;
import com.ffggffgfv.backend.entity.Shelf;
import com.ffggffgfv.backend.entity.ShelfProduct;
import com.ffggffgfv.backend.entity.StockLog;
import com.ffggffgfv.backend.mapper.ProductMapper;
import com.ffggffgfv.backend.mapper.ShelfMapper;
import com.ffggffgfv.backend.mapper.ShelfProductMapper;
import com.ffggffgfv.backend.mapper.StockLogMapper;
import com.ffggffgfv.backend.service.ShelfProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 货架商品服务实现类
 */
@Service
public class ShelfProductServiceImpl implements ShelfProductService {

    @Autowired
    private ShelfProductMapper shelfProductMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ShelfMapper shelfMapper;

    @Autowired
    private StockLogMapper stockLogMapper;

    /**
     * 获取货架上的所有商品
     *
     * @param shelfId 货架ID
     * @return 货架商品列表
     */
    @Override
    public List<ShelfProduct> findByShelfId(Long shelfId) {
        return shelfProductMapper.selectByShelfId(shelfId);
    }

    /**
     * 分页查询货架上的商品
     *
     * @param shelfId  货架ID
     * @param pageNum  页码
     * @param pageSize 每页大小
     * @return 分页结果
     */
    @Override
    public PageResult<ShelfProductDetailDTO> findByShelfIdWithPage(Long shelfId, int pageNum, int pageSize) {
        // 计算偏移量
        int offset = (pageNum - 1) * pageSize;

        // 查询总数
        long total = shelfProductMapper.countByShelfId(shelfId);

        // 查询当前页数据
        List<ShelfProduct> shelfProducts = shelfProductMapper.selectByShelfIdWithPagination(shelfId, offset, pageSize);

        // 转换为详情DTO
        List<ShelfProductDetailDTO> detailList = new ArrayList<>();
        for (ShelfProduct shelfProduct : shelfProducts) {
            Product product = productMapper.selectById(shelfProduct.getProductId());
            if (product != null) {
                ShelfProductDetailDTO detail = new ShelfProductDetailDTO();
                detail.setId(shelfProduct.getId());
                detail.setProductId(product.getId());
                detail.setProductName(product.getName());
                detail.setMainImageUrl(product.getMainImageUrl());
                detail.setPrice(product.getPrice());
                detail.setQuantity(shelfProduct.getQuantity());
                detail.setPosition(shelfProduct.getPosition());
                detail.setUpdateTime(shelfProduct.getUpdateTime());

                // 解析RFID标签JSON
                if (shelfProduct.getRfidTags() != null && !shelfProduct.getRfidTags().isEmpty()) {
                    detail.setRfidTags(JSON.parseArray(shelfProduct.getRfidTags(), String.class));
                } else {
                    detail.setRfidTags(new ArrayList<>());
                }

                detailList.add(detail);
            }
        }

        // 返回分页结果
        return new PageResult<>(detailList, total, pageNum, pageSize);
    }

    /**
     * 查询货架上的特定商品
     *
     * @param shelfId   货架ID
     * @param productId 商品ID
     * @return 货架商品对象
     */
    @Override
    public ShelfProduct findByShelfIdAndProductId(Long shelfId, Long productId) {
        return shelfProductMapper.selectByShelfIdAndProductId(shelfId, productId);
    }

    /**
     * 根据RFID标签查询商品
     *
     * @param rfidTag RFID标签
     * @return 包含货架和商品信息的Map
     */
    @Override
    public Map<String, Object> findByRfidTag(String rfidTag) {
        ShelfProduct shelfProduct = shelfProductMapper.selectByRfidTag(rfidTag);
        if (shelfProduct == null) {
            return null;
        }

        Product product = productMapper.selectById(shelfProduct.getProductId());
        Shelf shelf = shelfMapper.selectById(shelfProduct.getShelfId());

        Map<String, Object> result = new HashMap<>();
        result.put("rfidTag", rfidTag);
        result.put("productId", shelfProduct.getProductId());
        result.put("productName", product != null ? product.getName() : "未知商品");
        result.put("shelfId", shelfProduct.getShelfId());
        result.put("shelfName", shelf != null ? shelf.getName() : "未知货架");
        result.put("position", shelfProduct.getPosition());
        result.put("price", product != null ? product.getPrice() : null);
        result.put("mainImageUrl", product != null ? product.getMainImageUrl() : null);

        return result;
    }

    /**
     * 补货操作
     *
     * @param shelfId    货架ID
     * @param restockDTO 补货信息
     * @return 操作后的货架商品信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ShelfProductDetailDTO restock(Long shelfId, RestockDTO restockDTO) {
        // 检查货架是否存在
        Shelf shelf = shelfMapper.selectById(shelfId);
        if (shelf == null) {
            throw new RuntimeException("货架不存在");
        }

        // 检查商品是否存在
        Product product = productMapper.selectById(restockDTO.getProductId());
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        // 检查货架上是否已有该商品
        ShelfProduct existingProduct = shelfProductMapper.selectByShelfIdAndProductId(shelfId, restockDTO.getProductId());
        Date now = new Date();

        if (existingProduct != null) {
            // 更新现有商品数量和RFID标签
            existingProduct.setQuantity(existingProduct.getQuantity() + restockDTO.getQuantity());

            // 更新RFID标签
            List<String> existingTags;
            if (existingProduct.getRfidTags() != null && !existingProduct.getRfidTags().isEmpty()) {
                existingTags = JSON.parseArray(existingProduct.getRfidTags(), String.class);
            } else {
                existingTags = new ArrayList<>();
            }

            if (restockDTO.getRfidTags() != null) {
                existingTags.addAll(restockDTO.getRfidTags());
            }

            existingProduct.setRfidTags(JSON.toJSONString(existingTags));
            existingProduct.setUpdateTime(now);

            // 更新货架商品
            shelfProductMapper.update(existingProduct);
        } else {
            // 创建新的货架商品记录
            existingProduct = new ShelfProduct();
            existingProduct.setShelfId(shelfId);
            existingProduct.setProductId(restockDTO.getProductId());
            existingProduct.setQuantity(restockDTO.getQuantity());
            existingProduct.setPosition(restockDTO.getPosition());

            if (restockDTO.getRfidTags() != null) {
                existingProduct.setRfidTags(JSON.toJSONString(restockDTO.getRfidTags()));
            }

            existingProduct.setCreateTime(now);
            existingProduct.setUpdateTime(now);

            // 插入货架商品
            shelfProductMapper.insert(existingProduct);
        }

        // 记录库存变更日志
        StockLog stockLog = new StockLog();
        stockLog.setProductId(restockDTO.getProductId());
        stockLog.setShelfId(shelfId);
        stockLog.setChangeType(2); // 2-补货
        stockLog.setQuantity(restockDTO.getQuantity());
        stockLog.setOperatorId(restockDTO.getOperatorId());
        stockLog.setOperatorType(restockDTO.getOperatorType());
        stockLog.setReason(restockDTO.getReason());
        stockLog.setCreateTime(now);
        stockLogMapper.insert(stockLog);

        // 更新商品总库存
        product.setTotalStock(product.getTotalStock() + restockDTO.getQuantity());
        product.setUpdateTime(now);
        productMapper.update(product);

        // 构建返回结果
        ShelfProductDetailDTO detail = new ShelfProductDetailDTO();
        detail.setId(existingProduct.getId());
        detail.setProductId(product.getId());
        detail.setProductName(product.getName());
        detail.setMainImageUrl(product.getMainImageUrl());
        detail.setPrice(product.getPrice());
        detail.setQuantity(existingProduct.getQuantity());
        detail.setPosition(existingProduct.getPosition());
        detail.setUpdateTime(existingProduct.getUpdateTime());

        // 解析RFID标签JSON
        if (existingProduct.getRfidTags() != null && !existingProduct.getRfidTags().isEmpty()) {
            detail.setRfidTags(JSON.parseArray(existingProduct.getRfidTags(), String.class));
        } else {
            detail.setRfidTags(new ArrayList<>());
        }

        return detail;
    }

    /**
     * 移除货架上的商品
     *
     * @param shelfId      货架ID
     * @param productId    商品ID
     * @param quantity     移除数量，若为null则全部移除
     * @param reason       移除原因
     * @param rfidTags     要移除的RFID标签列表
     * @param operatorId   操作人ID
     * @param operatorType 操作人类型
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> removeProduct(Long shelfId, Long productId, Integer quantity, String reason,
                                             List<String> rfidTags, Long operatorId, Integer operatorType) {
        Map<String, Object> result = new HashMap<>();

        // 查询货架上的商品
        ShelfProduct shelfProduct = shelfProductMapper.selectByShelfIdAndProductId(shelfId, productId);
        if (shelfProduct == null) {
            throw new RuntimeException("货架上不存在该商品");
        }

        // 查询商品
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        Date now = new Date();
        int removedQuantity;
        List<String> removedRfidTags = new ArrayList<>();
        List<String> remainingRfidTags = new ArrayList<>();

        // 获取当前的RFID标签列表
        List<String> currentTags = new ArrayList<>();
        if (shelfProduct.getRfidTags() != null && !shelfProduct.getRfidTags().isEmpty()) {
            currentTags = JSON.parseArray(shelfProduct.getRfidTags(), String.class);
        }

        // 如果指定了RFID标签，则移除这些标签
        if (rfidTags != null && !rfidTags.isEmpty()) {
            for (String tag : currentTags) {
                if (rfidTags.contains(tag)) {
                    removedRfidTags.add(tag);
                } else {
                    remainingRfidTags.add(tag);
                }
            }
            removedQuantity = removedRfidTags.size();

            // 如果同时指定了数量，以RFID标签数量为准
            if (quantity != null && quantity != removedQuantity) {
                quantity = removedQuantity;
            }
        } else {
            // 如果未指定RFID标签，根据数量处理
            if (quantity == null || quantity >= shelfProduct.getQuantity()) {
                // 全部移除
                removedQuantity = shelfProduct.getQuantity();
                removedRfidTags.addAll(currentTags);
                remainingRfidTags = new ArrayList<>();
            } else {
                // 部分移除
                removedQuantity = quantity;
                // 如果有RFID标签，则移除相应数量的标签
                if (currentTags.size() >= quantity) {
                    for (int i = 0; i < currentTags.size(); i++) {
                        if (i < quantity) {
                            removedRfidTags.add(currentTags.get(i));
                        } else {
                            remainingRfidTags.add(currentTags.get(i));
                        }
                    }
                } else {
                    removedRfidTags.addAll(currentTags);
                    remainingRfidTags = new ArrayList<>();
                }
            }
        }

        // 更新货架商品记录
        if (shelfProduct.getQuantity() <= removedQuantity) {
            // 如果移除数量大于等于当前数量，则删除该货架商品
            shelfProductMapper.deleteByShelfIdAndProductId(shelfId, productId);
        } else {
            // 否则更新数量和RFID标签
            shelfProduct.setQuantity(shelfProduct.getQuantity() - removedQuantity);
            shelfProduct.setRfidTags(JSON.toJSONString(remainingRfidTags));
            shelfProduct.setUpdateTime(now);
            shelfProductMapper.update(shelfProduct);
        }

        // 记录库存变更日志
        StockLog stockLog = new StockLog();
        stockLog.setProductId(productId);
        stockLog.setShelfId(shelfId);
        stockLog.setChangeType(reason != null && reason.contains("销售") ? 1 : 4); // 1-销售 4-报损
        stockLog.setQuantity(-removedQuantity); // 负数表示减少
        stockLog.setOperatorId(operatorId);
        stockLog.setOperatorType(operatorType);
        stockLog.setReason(reason);
        stockLog.setCreateTime(now);
        stockLogMapper.insert(stockLog);

        // 更新商品总库存
        product.setTotalStock(product.getTotalStock() - removedQuantity);
        product.setUpdateTime(now);
        productMapper.update(product);

        // 组装返回结果
        result.put("shelfId", shelfId);
        result.put("productId", productId);
        result.put("removedQuantity", removedQuantity);
        result.put("removedRfidTags", removedRfidTags);
        result.put("remainingQuantity", shelfProduct.getQuantity() <= removedQuantity ? 0 : shelfProduct.getQuantity() - removedQuantity);
        result.put("remainingRfidTags", remainingRfidTags);

        return result;
    }

    /**
     * 批量补货操作
     *
     * @param shelfId         货架ID
     * @param batchRestockDTO 批量补货信息
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> batchRestock(Long shelfId, BatchRestockDTO batchRestockDTO) {
        Map<String, Object> result = new HashMap<>();
        int successCount = 0;
        int failCount = 0;
        List<Map<String, Object>> details = new ArrayList<>();

        for (RestockDTO item : batchRestockDTO.getItems()) {
            // 设置操作人信息
            if (item.getOperatorId() == null) {
                item.setOperatorId(batchRestockDTO.getOperatorId());
            }
            if (item.getOperatorType() == null) {
                item.setOperatorType(batchRestockDTO.getOperatorType());
            }

            try {
                ShelfProductDetailDTO detail = restock(shelfId, item);

                // 记录成功信息
                Map<String, Object> itemDetail = new HashMap<>();
                itemDetail.put("productId", item.getProductId());
                itemDetail.put("currentQuantity", detail.getQuantity());
                itemDetail.put("rfidTagsCount", detail.getRfidTags() != null ? detail.getRfidTags().size() : 0);
                details.add(itemDetail);

                successCount++;
            } catch (Exception e) {
                failCount++;
            }
        }

        result.put("successCount", successCount);
        result.put("failCount", failCount);
        result.put("details", details);

        return result;
    }
}
